package eu.smoothit.sis.admin.backendBean;

import java.util.ArrayList;
import java.util.List;

import javax.faces.context.FacesContext;
import javax.faces.event.PhaseId;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;

import eu.smoothit.sis.db.SisDAOFactory;
import eu.smoothit.sis.db.api.daos.IComponentConfigDAO;
import eu.smoothit.sis.db.impl.entities.ComponentConfigEntry;
import eu.smoothit.sis.admin.backendBean.superclass.DataTable;

/**
 * BackBean for Component Config module
 * 
 */
public class ComponentConfigBean extends DataTable<ComponentConfigEntry> {
	// Constants
	// ----------------------------------------------------------------------------------
	public static final String COMPONENT_NAME_IOP = eu.smoothit.sis.init.web.SisWebInitializer.COMPONENT_NAME_CONTR_IOP;// "Controler-IoP-Config"
	// TODO name convension not confirmed
	public static final String COMPONENT_NAME_GENRIC = "PARAM_GENERIC_PEER_RATING";
	// define DAO
	private IComponentConfigDAO dataDAO = (IComponentConfigDAO) SisDAOFactory
			.getFactory().createComponentConfigDAO();
	// dataTableColumn Names used in sorting
	private static String idValue = "id";
	private static String componentName = "component";
	private static String propertyName = "propName";
	private static String propertyValue = "value";
	// input value of searching
	private String keyword_componentName;
	private String keyword_propertyName;
	private String  keyword_componentName_picker;

	public String getKeyword_componentName_picker() {
		return keyword_componentName_picker;
	}

	public void setKeyword_componentName_picker(String keywordComponentNamePicker) {
		keyword_componentName_picker = keywordComponentNamePicker;
	}

	// wrap operation mode values in a array for Selection List
	public SelectItem[] getComponentNameList() {
		SelectItem[] definitions = new SelectItem[2];
		definitions[0] = new SelectItem(COMPONENT_NAME_IOP, "IoP",
				"This is for IoP", false);
		definitions[1] = new SelectItem(COMPONENT_NAME_GENRIC,
				"GenericPeerRating", "This is for Generic peer", false);
		return definitions;
	}

	// initialization
	public ComponentConfigBean() {
		// apiQuestions = new ComponentConfigEntry();
	}

	// setter and getter
	// ----------------------------------------------------------------------------------
	// searching input keywords
	public String getKeyword_componentName() {
		return keyword_componentName;
	}

	public void setKeyword_componentName(String keywordComponentName) {
		keyword_componentName = keywordComponentName;
	}

	public String getKeyword_propertyName() {
		return keyword_propertyName;
	}

	public void setKeyword_propertyName(String keywordPropertyName) {
		keyword_propertyName = keywordPropertyName;
	}

	// public ComponentConfigEntry getApiQuestions() {
	// return apiQuestions;
	// }
	//
	// public void setApiQuestions(ComponentConfigEntry apiQuestions) {
	// this.apiQuestions = apiQuestions;
	// }

	public String getIdValue() {
		return idValue;
	}

	public String getComponentName() {
		return componentName;
	}

	public String getPropertyName() {
		return propertyName;
	}

	public String getPropertyValue() {
		return propertyValue;
	}

	int count = 0;

	public List<ComponentConfigEntry> getDataList() {
		if (FacesContext.getCurrentInstance().getRenderResponse())
			refreshDataList();
		count = count + 1;
		System.err.println("getDataList:" + count);
		return dataList;
	}

	boolean searchModeMoreThanOnces = false;

	/**
	 * refresh data based on situation of searching/getALL/edit
	 */
	public void refreshDataList() {
		if (multiSearchMode) {
			if (searchModeMoreThanOnces) {
				multiColumnsSearch();
			}
			sort();
			// query again when refresh query result
			searchModeMoreThanOnces = true;
			// otherwise, load all when not in edit mode and not all rows of
			// current selected
		} else if (!editMode && !selectAll) {
			try {
				dataList = dataDAO.getAll();
			} catch (Exception e) {
				setErrorMessage(e.getMessage() + " Cause: " + e.getCause());
				e.printStackTrace();
			}
			sort();
		}
	}

	/**
	 * Searching more than one fields
	 */
	// ComponentConfigEntry Question;
	String keyword_componentName_old = "";
	String keyword_propertyName_old = "";

	public void multiColumnsSearch() {
		boolean isQuestion = false;
		// TODO validate at least one criteria before search
		ComponentConfigEntry Question;
		Question = new ComponentConfigEntry();

		if (keyword_componentName.trim().length() != 0) {
			Question.setComponent(keyword_componentName);
			isQuestion = true;
			keyword_componentName_old = keyword_componentName;
		}
		if (keyword_propertyName.trim().length() != 0) {
			Question.setPropName(keyword_propertyName);
			isQuestion = true;
			keyword_propertyName_old = keyword_propertyName;
		}
		if (isQuestion) {
			try {
				dataList = dataDAO.get(Question);
			} catch (Exception e) {
				setErrorMessage(e.getMessage() + " Cause: " + e.getCause());
				e.printStackTrace();
				// return false;
			}
			if (dataList.size() == 0) {
				setErrorMessage("Search Return No Result");
			}
		}
		// if no creterias given
		else {
			multiSearchMode = false;
			setErrorMessage("Please give at least one criteria for searching ");
		}
		// search criteria change, disable requery previous query
		searchModeMoreThanOnces = false;

	}

	/**
	 * Pick a predefined criteria for searching
	 * 
	 * @param event
	 */
	public void filterPickerListener(ValueChangeEvent event) {
		keyword_componentName_picker = (String) event.getNewValue();
		keyword_componentName=keyword_componentName_picker;
		// jump to stage of invoke application(refresh)
		 if (!event.getPhaseId().equals(PhaseId.INVOKE_APPLICATION)) {
		 event.setPhaseId(PhaseId.INVOKE_APPLICATION);
		 event.queue();
		 return;
		 }

	}

	/**
	 * overload actionAdd(E) as JSF web page allows methods without parameters
	 * only.
	 */
	public void actionAdd() {
		// disable search mode
		multiSearchMode = false;
		actionAdd(new ComponentConfigEntry());
	}

	@Override
	public void actionDelete() {
		// disable search mode
		multiSearchMode = false;
		List<ComponentConfigEntry> deleteItems = new ArrayList<ComponentConfigEntry>();
		for (int index = 0; index < dataList.size(); index++) {
			// Get selected items.
			if (isSelectedRow(index)) {
				deleteItems.add(dataList.get(index));
			}
		}
		if (deleteItems.isEmpty()) {
			setErrorMessage("Select at least one item to delete.");
			return;
		}
		String deletedItemsNames = "";
		try {
			for (ComponentConfigEntry deleteItem : deleteItems) {
				dataDAO.remove(deleteItem);
				deletedItemsNames = deletedItemsNames + "("
						+ deleteItem.getComponent() + ", "
						+ deleteItem.getPropName() + ");<br>";
			}
		} catch (Exception e) {
			setErrorMessage(e.getMessage() + " Cause: " + e.getCause());
			e.printStackTrace();
			return;
		}
		if (deletedItemsNames.length() > 0)
			setErrorMessage("Deleted entries: <br>" + deletedItemsNames);
	}

	// form actions
	// ----------------------------------------------------------------------------------
	/*
	 * save new added entries or modified exiting entry
	 */
	@Override
	public void actionSave() {
		List<ComponentConfigEntry> editItems = new ArrayList<ComponentConfigEntry>();
		for (int index = 0; index < dataList.size(); index++) {
			if (isEditModeRow(index)) {
				editItems.add(dataList.get(index));
			}
		}
		String addItemNames = "";
		String updatItemNames = "";
		try {
			for (ComponentConfigEntry editItem : editItems) {
				// id=0 stand for new added entry
				if (editItem.getId() == 0) {
					dataDAO.persist(editItem);
					addItemNames = addItemNames + "(" + editItem.getComponent()
							+ "," + editItem.getPropName() + ")";
				}

				else
					// otherwise, it is existing entry, update it.
					dataDAO.update(editItem);
				updatItemNames = updatItemNames + "(" + editItem.getComponent()
						+ "," + editItem.getPropName() + ")";
			}
			setErrorMessage("Add/Modified Entries: " + addItemNames
					+ updatItemNames);
		} catch (Exception e) {
			setErrorMessage(e.getMessage() + " Cause: " + e.getCause());
			e.printStackTrace();
			return;
		}
		// reload data.
		super.actionSave();
	}

	@Override
	public void actionRefresh() {
		// reset question each time
		// apiQuestions = new ComponentConfigEntry();
		// reset, hidden all input UI
		keyword_componentName = "";
		keyword_propertyName = "";
		keyword_componentName_picker="";
		super.actionRefresh();
		resetErrorMessage();
		count = 0;
	}

	/**
	 * Search data. Toggle search mode, load data and go to first page.
	 */
	public void actionSearch() {
		// reset search
		multiSearchMode = true;
		multiColumnsSearch();
	}

}
